package com.lwq.fast.log.fastlogserver.rabbitmq.config;


import com.lwq.fast.log.fastlogcore.constant.Constants;
import com.lwq.fast.log.fastlogserver.rabbitmq.listener.RabbitConsumerListener;
import org.springframework.amqp.core.AcknowledgeMode;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.amqp.rabbit.listener.MessageListenerContainer;
import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
import org.springframework.amqp.rabbit.listener.api.ChannelAwareMessageListener;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;


/**
 * rabbitmq 配置类
 *
 * @author 刘文强
 */
@Configuration
@ConditionalOnProperty(name = "active.client", havingValue = "rabbitMq")
public class RabbitMqConfig {
    @Value("${rabbitmq.config.host}")
    private String host;
    @Value("${rabbitmq.config.port}")
    private int port;
    @Value("${rabbitmq.config.virtual-host}")
    private String virtualHost;
    @Value("${rabbitmq.config.username}")
    private String username;
    @Value("${rabbitmq.config.password}")
    private String password;

    @Bean
    public ConnectionFactory connectionFactory() {
        CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
        connectionFactory.setHost(host);
        connectionFactory.setPort(port);
        connectionFactory.setVirtualHost(virtualHost);
        connectionFactory.setUsername(username);
        connectionFactory.setPassword(password);
        return connectionFactory;
    }

    @Bean
    @ConditionalOnBean(ConnectionFactory.class)
    public RabbitAdmin rabbitAdmin() {
        return new RabbitAdmin(connectionFactory());
    }

    @Bean
    @ConditionalOnProperty(name = "active.client", havingValue = "rabbitMq")
    public ChannelAwareMessageListener consumerListener() {
        return new RabbitConsumerListener();
    }

    @Bean
    @ConditionalOnBean({ConnectionFactory.class, RabbitAdmin.class, ChannelAwareMessageListener.class})
    public MessageListenerContainer messageListenerContainer() {
        SimpleMessageListenerContainer messageListenerContainer = new SimpleMessageListenerContainer();
        messageListenerContainer.setConnectionFactory(connectionFactory());
        messageListenerContainer.setAmqpAdmin(rabbitAdmin());
        messageListenerContainer.setPrefetchCount(1);
        messageListenerContainer.setAcknowledgeMode(AcknowledgeMode.MANUAL);
        messageListenerContainer.setMessageListener(consumerListener());
        messageListenerContainer.setQueues(getQueue());
        return messageListenerContainer;
    }

    @Bean
    public DirectExchange directExchange() {
        DirectExchange directExchange = new DirectExchange(Constants.EXCHANGE, true, false);
        directExchange.setAdminsThatShouldDeclare(rabbitAdmin());
        return directExchange;
    }

    @Bean
    public Queue getQueue() {
        Queue queue = new Queue(Constants.QUEUE, true, false, false);
        queue.setAdminsThatShouldDeclare(rabbitAdmin());
        return queue;
    }

    @Bean
    public Binding directQueueBinding() {
        Binding binding = new Binding(Constants.QUEUE, Binding.DestinationType.QUEUE, Constants.EXCHANGE, Constants.ROUTING_KEY, null);
        binding.setAdminsThatShouldDeclare(rabbitAdmin());
        return binding;
    }
}